<?php
/**
 * Prado Portal.
 *
 * @author Steen Rabol <steen.rabol@gmail.com>
 * @link http://www.pradoportal.dk/
 * @copyright Copyright &copy; 2006,2007,2008 Steen Rabol
 * @license http://www.pradoportal.dk
 * @version $Id: PortalOpenId.php 431 2011-01-05 11:58:18Z steen.rabol $
 * @package Pradoportal.Common
 *
 */

/**
 *
 * @package Pradoportal.Common
 */

Prado::using('System.Util.TVarDumper');
// We need to set the include path
$path_extra	= Prado::getPathOfNamespace('Application.Common.3rdParty.OpenId') .'/';
$incpath	= ini_get('include_path');
$incpath	= $path_extra . PATH_SEPARATOR . $incpath;
ini_set('include_path', $incpath);

// If we are running on Windows there is no random device
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
{
	define("Auth_OpenID_RAND_SOURCE",null);
}

require_once "Auth/OpenID/Consumer.php";

// Require the "file store" module, which we'll need to store OpenID information.
require_once "Auth/OpenID/FileStore.php";

// Require the Simple Registration extension API.
require_once "Auth/OpenID/SReg.php";

//Require the PAPE extension module.
require_once "Auth/OpenID/PAPE.php";


class PortalOpenId extends TComponent
{
	private $_store		= null;
	private $_consumer	= null;
	private $_app		= null;

	public function __construct($store = null, $consumer = null)
	{
		$this->Application	= Prado::getApplication();
	}

	public function getStore()
	{
		if($this->_store	=== null)
		{
			$store_path	= $this->Application->PortalBasePath . '/storage/OpenId';
			PortalUtil::CreateDirStructure($store_path);

			$this->_store		= new Auth_OpenID_FileStore($store_path);
		}

		return $this->_store;
	}

	public function setStore($value)
	{
		$this->_store	= $value;
	}

	public function getConsumer()
	{
		if($this->_consumer === null)
		{
			$this->_consumer	= new Auth_OpenID_Consumer($this->Store);
		}

		return $this->_consumer;
	}

	public function setConsumer($value)
	{
		$this->_consumer	= $value;
	}

	public function getApplication()
	{
		return $this->_app;
	}

	public function setApplication($value)
	{
		$this->_app	=$value;

	}

	public function VerifyOpenId($openid_url,$trusturl, $returntourl)
	{
		// Begin the OpenID authentication process.
		$consumer	= $this->getConsumer();
		$auth_request = $consumer->begin($openid_url);

		// No auth request means we can't begin OpenID.
		if (!$auth_request)
		{
			$msg= "Authentication error; not a valid OpenID.";
			$this->reportError(0,$msg);
		}

		if ($auth_request->shouldSendRedirect())
		{
			$redirect_url	= $auth_request->redirectURL($trusturl,$returntourl);

			// If the redirect URL can't be built, display an error message.
			if (Auth_OpenID::isFailure($redirect_url))
			{
				$msg = "Could not redirect to server: " . $redirect_url->message;
				$this->reportError(0, $msg);
			}
			else
			{
				$app = $this->getApplication();
				$r = $app->Response;
				// Send redirect.
				$r->redirect($redirect_url);
			}
		}
		else
		{
			// Generate form markup and render it.
			$form_id = 'openid_message';
			$form_html = $auth_request->htmlMarkup($trusturl, $returntourl,false, array('id' => $form_id));
			// Display an error if the form markup couldn't be generated;
			// otherwise, render the HTML.
			if (Auth_OpenID::isFailure($form_html))
			{
				$msg = "Could not redirect to server: " . $form_html->message;
				$this->reportError(1, $msg);
			}
			else
			{
				print $form_html;
			}
		}
	}

	public function BeginSimpleRegistration($openid_url,$trusturl, $returntourl)
	{
		// Begin the OpenID authentication process.
		$consumer	= $this->getConsumer();
		$auth_request = $consumer->begin($openid_url);

		// No auth request means we can't begin OpenID.
		if (!$auth_request)
		{
			$msg= "Authentication error; not a valid OpenID.";
			$this->reportError(1,$msg);
		}

		try
		{
			$sreg_request = Auth_OpenID_SRegRequest::build(
								 // Required
								 array('nickname','email'),
								 // Optional
								 array('fullname', 'language'));
		}
		catch(Exception $e)
		{
			$this->reportError(1, $e->getMessage());
		}

		if ($sreg_request)
		{
			$auth_request->addExtension($sreg_request);
		}

		// Redirect the user to the OpenID server for authentication.
		// Store the token for this authentication so we can verify the
		// response.

		// For OpenID 1, send a redirect.  For OpenID 2, use a Javascript
		// form to send a POST request to the server.

		if ($auth_request->shouldSendRedirect())
		{
			$redirect_url	= $auth_request->redirectURL($trusturl,$returntourl);

			// If the redirect URL can't be built, display an error message.
			if (Auth_OpenID::isFailure($redirect_url))
			{
				$msg = "Could not redirect to server: " . $redirect_url->message;
				$this->reportError(1, $msg);
			}
			else
			{
				$app = $this->getApplication();
				$r = $app->Response;
				// Send redirect.
				$r->redirect($redirect_url);
			}
		}
		else
		{
			// Generate form markup and render it.
			$form_id = 'openid_message';
			$form_html = $auth_request->htmlMarkup($trusturl, $returntourl,false, array('id' => $form_id));
			// Display an error if the form markup couldn't be generated;
			// otherwise, render the HTML.
			if (Auth_OpenID::isFailure($form_html))
			{
				$msg = "Could not redirect to server: " . $form_html->message;
				$this->reportError(1, $msg);
			}
			else
			{
				print $form_html;
			}
		}
	}

	public function CompleteSimpleRegistration($returntourl)
	{
		$sreg	= array();
		$consumer	= $this->getConsumer();

		// Complete the authentication process using the server's
		// response.
		$response = $consumer->complete($returntourl);

		// Check the response status.
		if ($response->status == Auth_OpenID_CANCEL)
		{
			// This means the authentication was cancelled.
			$msg = 'Verification cancelled.';
			$this->reportError(0,$msg);
		}
		else if ($response->status == Auth_OpenID_FAILURE)
		{
			// Authentication failed; display the error message.
			if($response->message === 'Server denied check_authentication')
			{
				$msg = "Did you remember to fill in the complete OpenId URL?";
			}
			else
			{
				$msg = "OpenID authentication failed: " . $response->message;
			}

			$this->reportError(0,$msg);
		}
		else if ($response->status == Auth_OpenID_SUCCESS)
		{
			// This means the authentication succeeded; extract the
			// identity URL and Simple Registration data (if it was
			// returned).
			$openid = $response->getDisplayIdentifier();
			$esc_identity = htmlentities($openid);

			$sreg['openid_url']  = $esc_identity;

			if ($response->endpoint->canonicalID)
			{
				$escaped_canonicalID = htmlentities($response->endpoint->canonicalID);
				$success .= '  (XRI CanonicalID: '.$escaped_canonicalID.') ';
			}

			$sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
			$sreg = array_merge($sreg,$sreg_resp->contents());
		}

		return $sreg;
	}

	public function gotoPage($pagePath,$getParameters = null)
	{
		$this->Application->Response->redirect($this->Application->Service->constructUrl($pagePath,$getParameters));
	}

	public function reportError($errorCode, $errorMsg)
	{
		$this->gotoPage('System.ErrorReport',array('id'=>$errorCode,'msg' => urldecode($this->getApplication()->getSecurityManager()->hashData($errorMsg))));
	}

	public function CompleteVerifyOpenId($returntourl)
	{
		$consumer	= $this->getConsumer();

		// Complete the authentication process using the server's
		// response.
		$response = $consumer->complete($returntourl);

		// Check the response status.
		if ($response->status == Auth_OpenID_CANCEL)
		{
			// This means the authentication was cancelled.
			$this->reportError(0,'Verification cancelled.');
		}
		else if ($response->status == Auth_OpenID_FAILURE)
		{
			// Authentication failed; display the error message.
			die($response->message);
			$this->reportError(0,"OpenID authentication failed: " . $response->message);
		}
		else if ($response->status == Auth_OpenID_SUCCESS)
		{
			return true;
		}

		return false;
	}
}
?>